﻿#include"XQHttpHeadRequest.h"
#include<QDebug>
XQHttpHeadRequest::XQHttpHeadRequest(const QByteArray& data)
{
	m_type = Http::Head::Request;
	if (data.isEmpty())
		init();
	else
		setData(data);
}

QByteArray XQHttpHeadRequest::header_toByteArray() const
{
	return request_toByteArray()+" "+ m_path.toUtf8()+ args_toByteArray()+" "+ versions_toByteArray() + "\r\n" + XQHttpHeadObject::header_toByteArray();
}

HttpRequestType XQHttpHeadRequest::requestType() const
{
	return m_requestType;
}

QByteArray XQHttpHeadRequest::request_toByteArray() const
{
	if (m_requestType == HttpRequestType::GET)
		return "GET";
	else if (m_requestType == HttpRequestType::POST)
		return "Post";
	return QByteArray();
}

HttpProtocol XQHttpHeadRequest::protocol() const
{
	return m_protocol;
}

QByteArray XQHttpHeadRequest::protocol_toByteArray() const
{
	if (m_protocol == HttpProtocol::http)
		return "http";
	else if (m_protocol == HttpProtocol::https)
		return "https";
	return QByteArray();
}

QString XQHttpHeadRequest::path() const
{
	return m_path;
}

QString XQHttpHeadRequest::url() const
{
	auto url= protocol_toByteArray()+"://" + hostPort();
	if (!m_path.isEmpty())
		url += ("/" + m_path);
	url += args_toByteArray();
	return url;
}

QByteArray XQHttpHeadRequest::args_toByteArray() const
{
	if (m_Args.isEmpty())
		return QByteArray();
	QByteArray byte="?";
	for (auto it = m_Args.begin(); it != m_Args.end(); it++)
	{
		auto& key = it.key();
		auto& value = it.value();
		byte += (key + "=" + value + "&");
	}
	if (byte.endsWith("&"))
		byte.remove(byte.size() - 1, 1);
	return byte;
}

const QHash<QByteArray, QByteArray>& XQHttpHeadRequest::args() const
{
	return m_Args;
}

QHash<QByteArray, QByteArray>& XQHttpHeadRequest::args()
{
	return m_Args;
}

QByteArray XQHttpHeadRequest::args(const QByteArray& argsName) const
{
	return m_Args[argsName];
}

void XQHttpHeadRequest::setData(const QByteArray& data)
{
	QByteArray buff;
	auto nSel = data.indexOf("\r\n\r\n");
	if (nSel != -1)
		buff = data.left(nSel + 2);
	else
		buff = data;
	auto list = buff.split('\n');
	if (list.isEmpty())
		return;
	//get/post 判断
	auto type = list[0].trimmed();
	if (QString(type).contains("GET", Qt::CaseSensitivity::CaseInsensitive))
		m_requestType = HttpRequestType::GET;
	else if (QString(type).contains("POST", Qt::CaseSensitivity::CaseInsensitive))
		m_requestType = HttpRequestType::POST;
	auto front = type.indexOf(" ");
	auto args= type.indexOf("?",front+1);
	auto last = type.lastIndexOf(" ");
	//路径设置
	if (front != 0 && last != 0)
		m_path = type.mid(front + 1, (args != -1&& args<last)? args - front-1 :last - front-1).trimmed();
	//参数设置
	if (args != -1 && args < last)
	{
		auto str = type.mid(args+1, last-args).trimmed();
		auto list = str.split('&');
		for (auto &row:list)
		{
			auto keyValue = row.split('=');
			if (keyValue.isEmpty())
				continue;
			QByteArray value;
			if (keyValue.size() > 1)
				value = keyValue[1];
			m_Args[keyValue[0]] = value;
		}
		//qDebug() << list;
	}
	setVersions(getVersions(type.mid(last + 1).trimmed()));
	list.pop_front();
	setHeader(list);
	//内容
	auto content = data.mid(nSel + 4);
	if (content.size()==headContentLength())
	{
		m_data = data;
	}
}

void XQHttpHeadRequest::setRequestType(HttpRequestType type)
{
	m_requestType = type;
}

void XQHttpHeadRequest::setProtocol(HttpProtocol protocol)
{
	m_protocol = protocol;
}

void XQHttpHeadRequest::setArgs(const QByteArray& argsName, const QByteArray& argsValue)
{
	m_Args[argsName] = argsValue;
}

void XQHttpHeadRequest::clear_args()
{
	m_Args.clear();
}

void XQHttpHeadRequest::clear()
{
	XQHttpHeadObject::clear();
	clear_args();
	m_protocol = HttpProtocol::http;
	m_requestType = HttpRequestType::GET;
	m_path.clear();
}

void XQHttpHeadRequest::setUrl(const QByteArray& data)
{
	auto one = data.indexOf("://");
	if (one == -1)
		return;
	//HttpProtocol 判断
	auto Protocol = QString(data.left(one));
	if (Protocol.contains("http", Qt::CaseInsensitive))
		setProtocol(HttpProtocol::http);
	else if (Protocol.contains("https", Qt::CaseInsensitive))
		setProtocol(HttpProtocol::https);
	auto two = data.indexOf("/", one + 3);
	//主机和端口解析
	{
		QString hostPort=(two != -1) ? (data.mid(one + 3, two - one - 3)) : (data.mid(one + 3));
		auto list = hostPort.split(":");
		if (list.isEmpty())
			return;
		QString host = list[0];
		int port = 80;
		if (list.size() > 1)
			port = list[1].toInt();
		else if (protocol() == HttpProtocol::http)
			port = 80;
		else if (protocol() == HttpProtocol::https)
			port = 443;
		setHostPort(host,port);
	}
	if (two == -1)
		return;
	//路径设置
	auto args = data.indexOf("?", two + 1);
	//路径设置
	m_path = (args != -1) ? (data.mid(two,args-two)) : (data.mid(two));
	if (args == -1)
		return;
	auto str = data.mid(args+1);
	auto list = str.split('&');
	for (auto& row : list)
	{
		auto keyValue = row.split('=');
		if (keyValue.isEmpty())
			continue;
		QByteArray value;
		if (keyValue.size() > 1)
			value = keyValue[1];
		m_Args[keyValue[0]] = value;
	}
}

void XQHttpHeadRequest::init()
{
	XQHttpHeadObject::init();
	setRequestType(Http::GET);
	setHeader("Content-Type","application/x-www-form-urlencoded");
	//setHeader("Connection", "Keep-Alive");
	setHeader("User-Agent", "Mozilla/5.0");
	setHeader("Accept-Encoding", "gzip,deflate");
}
